﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using MishraReader.Entities;
using MishraReader.Services;
using MishraReader.ViewModels;
using MishraReader.ViewModels.Settings;

#if !WINRT
using System.Windows.Media;
#else
using Windows.UI;
using Windows.UI.Xaml.Media;
#endif

namespace MishraReader.PlatformVMs
{
    public class SettingsViewModel : TaskViewModelBase, ISettingsViewModel
    {
        private readonly ILightWeakEventManager _eventManager;
        private readonly IGoogleReaderService _gService;
        private readonly IOptionsManager _optionsManager;
        private readonly Func<IShareServicePackage, ServiceAccountViewModel> _serviceAccountFactory;
        private readonly IShareServicesProvider _servicesProvider;
        private SolidColorBrush _initialColorBrush;
        private bool _markSelectedItemAsRead;
        private int _maxItemsByRequest;
        private int _refreshInterval;
        private SolidColorBrush _selectedAccentColor;
        private BackgroundImage _selectedBackground;
        private int _selectedHeaderIndex;
        private string _selectedSortOption;
        private int _selectedTabIndex;

        private bool _showInTaskBar;
        private bool _showOnlyPostSummary;
        private bool _useNotificationIcon;

        /// <summary>
        ///   Ctr
        /// </summary>
        public SettingsViewModel(IOptionsManager optionsManager,
                                 IGoogleReaderService gService,
                                 ILightWeakEventManager eventManager,
                                 IShareServicesProvider servicesProvider,
                                 Func<IShareServicePackage, ServiceAccountViewModel> serviceAccountFactory)
        {
            _optionsManager = optionsManager;
            _gService = gService;
            _eventManager = eventManager;
            _servicesProvider = servicesProvider;
            _serviceAccountFactory = serviceAccountFactory;
            OkCommand = new RelayCommand(ExecuteOkCommand);
            CancelCommand = new RelayCommand(ExecuteCancelCommand);
            DisconnectCommand = new RelayCommand(ExecuteDisconnectCommand);

            SortOptions = new List<string>
                              {
                                  Strings.OrderByPublicationDateDesc,
                                  Strings.OrderByPublicationDateAsc
                              };

            Headers = new[] {Strings.SettingsSmall, Strings.AboutSmall};

            Load();
        }

        public List<SolidColorBrush> AccentColors { get; private set; }


        public List<ServiceAccountViewModel> AvailableBookmarkServices { get; private set; }
        public List<ServiceAccountViewModel> AvailableShareServices { get; private set; }
        public List<BackgroundImage> Backgrounds { get; private set; }
        public ICommand CancelCommand { get; private set; }

        public String ConnectedSince
        {
            get
            {
                var delta = DateTime.UtcNow - _gService.Connector.ConnectedAt;

                if (delta.Days < 1)
                    return string.Format("{0:hh':'mm':'ss}", delta);

                return string.Format("{1} day(s) {0:hh':'mm':'ss}", delta, delta.Days);
            }
        }

        public ICommand DisconnectCommand { get; private set; }
        public IEnumerable<string> Headers { get; private set; }


        public bool MarkSelectedItemAsRead
        {
            get { return _markSelectedItemAsRead; }
            set
            {
                Set(ref _markSelectedItemAsRead, value);
            }
        }

        public int MaxItemsByRequest
        {
            get { return _maxItemsByRequest; }
            set
            {
                Set(ref _maxItemsByRequest, value);
            }
        }

        public ICommand OkCommand { get; private set; }

        public int RefreshInterval
        {
            get { return _refreshInterval; }
            set
            {
                if (_refreshInterval != value)
                {
                    _refreshInterval = value;
                    RaisePropertyChanged();
                }
            }
        }

        public SolidColorBrush SelectedAccentColor
        {
            get { return _selectedAccentColor; }
            set
            {
                if (_selectedAccentColor != value)
                {
                    _selectedAccentColor = value;
                    _optionsManager.AccentColorCode = SelectedAccentColor.Color.GetHexadecimalValue();
                    _optionsManager.UpdateAccentColor();
                    RaisePropertyChanged();
                }
            }
        }

        public BackgroundImage SelectedBackground
        {
            get { return _selectedBackground; }
            set
            {
                Set(ref _selectedBackground, value);
            }
        }

        public ObservableCollection<ServiceAccountViewModel> SelectedBookmarkServices { get; private set; }

        public int SelectedHeaderIndex
        {
            get { return _selectedHeaderIndex; }
            set
            {
                Set(ref _selectedHeaderIndex, value);
            }
        }

        public ObservableCollection<ServiceAccountViewModel> SelectedShareServices { get; private set; }


        public string SelectedSortOption
        {
            get { return _selectedSortOption; }
            set
            {
                Set(ref _selectedSortOption, value);
            }
        }

        public int SelectedTabIndex
        {
            get { return _selectedTabIndex; }
            set
            {
                Set(ref _selectedTabIndex, value);
            }
        }

        public bool ShowInTaskBar
        {
            get { return _showInTaskBar; }
            set
            {
                Set(ref _showInTaskBar, value);
            }
        }

        public bool ShowOnlyPostSummary
        {
            get { return _showOnlyPostSummary; }
            set
            {
                Set(ref _showOnlyPostSummary, value);
            }
        }

        public List<String> SortOptions { get; private set; }

        public bool UseNotificationIcon
        {
            get { return _useNotificationIcon; }
            set
            {
                Set(ref _useNotificationIcon, value);
            }
        }

        public String UserName
        {
            get { return _gService.Connector.UserName; }
        }

        /// <summary>
        ///   Dtr
        /// </summary>
        public override void Cleanup()
        {
            foreach (var service in AvailableShareServices)
            {
                service.PropertyChanged -= service_PropertyChanged;
            }

            foreach (var service in AvailableBookmarkServices)
            {
                service.PropertyChanged -= service_PropertyChanged;
            }
            base.Cleanup();
        }

        private void ExecuteCancelCommand()
        {
            SelectedAccentColor = _initialColorBrush;
            _eventManager.Send(ApplicationMessages.NavigationMessage, "Root");
        }

        /// <summary>
        ///   Disconnect user and navigate to SignInView
        /// </summary>
        private async void ExecuteDisconnectCommand()
        {
            _optionsManager.Login = string.Empty;
            _optionsManager.Password = string.Empty;
            await _optionsManager.Persist();

            await _gService.Disconnect();
            _eventManager.Send(ApplicationMessages.Disconnected);
        }

        private async void ExecuteOkCommand()
        {
            SaveSettings();

            await _optionsManager.Persist();

            _eventManager.Send(ApplicationMessages.NavigationMessage, "Root");
        }

        /// <summary>
        ///   LoadAsync data
        /// </summary>
        private void Load()
        {
            LoadDisplaySettings();
            LoadAccountsSettings();
            LoadNetwordSettings();
        }

        /// <summary>
        ///   LoadAsync all accounts settings
        /// </summary>
        private void LoadAccountsSettings()
        {
            AvailableShareServices = _servicesProvider.AvailableServices
                .Where(s => s.Service.ServiceType == ServiceType.Share)
                .Select(s => _serviceAccountFactory(s))
                .ToList();

            AvailableBookmarkServices = _servicesProvider.AvailableServices
                .Where(s => s.Service.ServiceType == ServiceType.Bookmark)
                .Select(s => _serviceAccountFactory(s))
                .ToList();

            foreach (var service in AvailableShareServices)
            {
                var account = _optionsManager.GetServiceAccount(service.ServicePackage);
                if (account != null)
                {
                    service.IsActivated = true;
                    service.ServiceUserName = account.UserName;
                    service.ServicePassword = account.Password;
                    service.ServiceToken = account.Token;
                }
            }

            foreach (var service in AvailableBookmarkServices)
            {
                var account = _optionsManager.GetServiceAccount(service.ServicePackage);
                if (account != null)
                {
                    service.IsActivated = true;
                    service.ServiceUserName = account.UserName;
                    service.ServicePassword = account.Password;
                    service.ServiceToken = account.Token;
                }
            }

            SelectedShareServices = new ObservableCollection<ServiceAccountViewModel>();
            SelectedBookmarkServices = new ObservableCollection<ServiceAccountViewModel>();

            foreach (var service in AvailableShareServices)
            {
                if (service.IsActivated)
                    SelectedShareServices.Add(service);

                service.PropertyChanged += service_PropertyChanged;
            }

            foreach (var service in AvailableBookmarkServices)
            {
                if (service.IsActivated)
                    SelectedBookmarkServices.Add(service);

                service.PropertyChanged += service_PropertyChanged;
            }
        }

        /// <summary>
        ///   LoadAsync display settings
        /// </summary>
        private void LoadDisplaySettings()
        {
            AccentColors = new List<SolidColorBrush>(8)
                               {
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0x1B, 0xA1, 0xE2)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0x8C, 0xBF, 0x26)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0x33, 0x99, 0x33)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0x00, 0x97)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0x96, 0x09)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0xE6, 0x71, 0xB8)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0xA2, 0x00, 0xFF)),
                                   new SolidColorBrush(Color.FromArgb(0xFF, 0xE5, 0x14, 0x00))
                               };

            if (String.IsNullOrEmpty(_optionsManager.AccentColorCode) == false)
            {
                try
                {
                    var color = ColorExtensions.GetColorFromHexValue(_optionsManager.AccentColorCode);
                    SelectedAccentColor = AccentColors.FirstOrDefault(a => a.Color == color);
                }
                catch
                {
                }
            }

            if (SelectedAccentColor == null)
                SelectedAccentColor = AccentColors[0];

            _initialColorBrush = SelectedAccentColor;
        
            Backgrounds = new List<BackgroundImage>
                              {
                                  new BackgroundImage
                                      {
                                          Name = "background1_HD.jpg",
                                          ImageSource = new Uri("pack://application:,,,/MishraReader;component/Assets/Backgrounds/background1_LD.jpg")
                                      },
                                  new BackgroundImage
                                      {
                                          Name = "background2_HD.jpg",
                                          ImageSource = new Uri("pack://application:,,,/MishraReader;component/Assets/Backgrounds/background2_LD.jpg")
                                      },
                                  new BackgroundImage
                                      {
                                          Name = "background3_HD.jpg",
                                          ImageSource = new Uri("pack://application:,,,/MishraReader;component/Assets/Backgrounds/background2_LD.jpg")
                                      }
                              };

            SelectedBackground = Backgrounds
                .FirstOrDefault(b => b.Name == _optionsManager.Background) ?? Backgrounds[0];

            ShowInTaskBar = _optionsManager.ShowInTaskbar;
            ShowOnlyPostSummary = _optionsManager.ShowOnlyPostSummary;
            UseNotificationIcon = _optionsManager.UseNotificationIcon;
            MarkSelectedItemAsRead = _optionsManager.MarkSelectedItemAsRead;

            SelectedSortOption = _optionsManager.OrderByPublicationDateDesc
                                     ? Strings.OrderByPublicationDateDesc
                                     : Strings.OrderByPublicationDateAsc;
        }

        private void LoadNetwordSettings()
        {
            RefreshInterval = _optionsManager.RefreshFrequency*-1;
            MaxItemsByRequest = _optionsManager.MaxItemsByRequest;
        }

        /// <summary>
        ///   Save display settings
        /// </summary>
        private async void SaveSettings()
        {
            // Display settings
            _optionsManager.AccentColorCode = SelectedAccentColor.Color.GetHexadecimalValue();

            _optionsManager.Background = SelectedBackground.Name;

            _optionsManager.ShowInTaskbar = ShowInTaskBar;
            _optionsManager.ShowOnlyPostSummary = ShowOnlyPostSummary;
            _optionsManager.UseNotificationIcon = UseNotificationIcon;

            var services = from service in SelectedShareServices.Concat(SelectedBookmarkServices)
                           where service.IsActivated && service.IsConfigured
                           select new ShareServiceAccount(service.ServicePackage)
                                      {
                                          UserName = service.ServiceUserName,
                                          Password = service.ServicePassword,
                                          Token = service.ServiceToken
                                      };

            _optionsManager.ReplaceActivatedServices(services);


            // Nework settings
            _optionsManager.RefreshFrequency = RefreshInterval*-1;
            _optionsManager.MaxItemsByRequest = MaxItemsByRequest;
            _optionsManager.MarkSelectedItemAsRead = MarkSelectedItemAsRead;

            var orderBy = SelectedSortOption == Strings.OrderByPublicationDateDesc;
            if (_optionsManager.OrderByPublicationDateDesc != orderBy)
            {

                await _gService.Connector.SetSortPreferenceAsync(_optionsManager.OrderByPublicationDateDesc);
                _optionsManager.OrderByPublicationDateDesc = orderBy;
                
            }


            _optionsManager.UpdateAccentColor();
        }


        /// <summary>
        ///   Service activated ?
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="e"> </param>
        private void service_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsActivated")
            {
                var serviceAccount = (ServiceAccountViewModel)sender;

                if (serviceAccount.ServicePackage.Service.ServiceType == ServiceType.Share)
                {
                    if (serviceAccount.IsActivated)
                        SelectedShareServices.Add(serviceAccount);
                    else
                        SelectedShareServices.Remove(serviceAccount);
                }
                else
                {
                    if (serviceAccount.IsActivated)
                        SelectedBookmarkServices.Add(serviceAccount);
                    else
                        SelectedBookmarkServices.Remove(serviceAccount);
                }
            }
        }

        public class BackgroundImage
        {
            public Uri ImageSource { get; set; }
            public String Name { get; set; }
        }
    }
}